package modulesAPI.v2.basics;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.Collection;
import java.util.LinkedList;

import javax.swing.BoxLayout;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;

import com.caterina.components.CButton;
import com.caterina.components.CLabel;
import com.caterina.components.CPanel;
import com.caterina.components.CLabel.LabelType;
import com.caterina.resources.CModules;
import com.caterina.resources.CWords;
import modulesAPI.v2.CollectionButtonListener;
import modulesAPI.v2.ElementsListener;
import modulesAPI.v2.Module;
import modulesAPI.v2.ViewType;

public class ModCollectionViewer extends ModCollection{
	/**
	 * Crea un nuovo modulo per l'inserimento/rappresentazione di una collezione di moduli
	 * che ne consente anche la visualizzazione e la modifica.
	 * */
	public ModCollectionViewer(Module<?> ownerModule,Collection<Module<?>> content, String tag, String description,ViewType viewType,int...options) {
		this(ownerModule, content,new EmptyModule(), tag, description, viewType,options);
	}
	/**
	 * Crea un nuovo modulo per l'inserimento/rappresentazione di una collezione di moduli
	 * che ne consente anche la visualizzazione e la modifica.
	 * */
	public ModCollectionViewer(Module<?> ownerModule,Collection<Module<?>> content,Module<?> addModule, String tag, String description,ViewType viewType,int...options) {
		super(ownerModule, content, tag, description, viewType,options);
			for(int opt:options){
				switch (opt){
					case HIDE_ADD: {this.addEn=false; break;}
					case HIDE_REMOVE: {this.removeEn=false; break;}
					default: {this.lastIndex=opt; break;}
				}
			}
			this.addModule=addModule;
			this.addModule.addModuleChangedListener(this);
			this.collectionButtonListeners=new LinkedList<CollectionButtonListener>();
	}
	public void refreshAddModule(){
		if (this.addMode){
			this.viewerScroll.removeAll();
			this.viewerScroll.add(this.addModule.getPanel());
		}
	}
	private CPanel createViewer(){
		if (this.addMode){return this.addModule.getPanel();}
		if (this.currentViewed!=null)this.currentViewed.removeModuleChangedListener(this);
		this.currentViewed=this.listMod.getSelectedContent();
		currentViewed.addModuleChangedListener(this);
		CPanel retPanel=currentViewed.getPanel();
		return retPanel;
	}
	private CPanel createList(){
		if (this.listMod!=null)lastIndex=listMod.getSelectedIndex();
		this.listMod=new ModCollection(this, this.getContent(), "NO_CONTENT","NO_CONTENT", this.getViewType(),lastIndex);
		CPanel mainPanel=new CPanel(new BorderLayout());
		CPanel bottomPanel=new CPanel(new BorderLayout());
		if (this.addEn){
			bottomPanel.add(new CButton("ADD") {
			@Override
			public void onFocus() {}			
			@Override
			public void onAction() {
				ModCollectionViewer.this.fireCollectionButtonListener(ModCollectionViewer.ADD);
				addMode=true;
				fireModuleChanged(ModCollectionViewer.this);
			}
			private static final long serialVersionUID = 1L;
		},BorderLayout.CENTER);
		}
		if(this.removeEn){	
			bottomPanel.add(new CButton("REMOVE") {
				@Override
				public void onFocus() {}				
				@Override
				public void onAction() {
					ModCollectionViewer.this.fireCollectionButtonListener(ModCollectionViewer.REMOVE);
					ModCollectionViewer.this.remove(ModCollectionViewer.this.getSelectedContent());
				}
				private static final long serialVersionUID = 1L;
			},BorderLayout.EAST);
		}
		mainPanel.add(bottomPanel,BorderLayout.SOUTH);
		mainPanel.add(this.listMod.getPanel(),BorderLayout.CENTER);
		if (this.getHierachyNumber()>0)mainPanel.setPreferredSize(new Dimension(200,250));
		else mainPanel.setMinimumSize(new Dimension(250,0));
		return mainPanel;
	}
	/**
	 * Abilita/Disabilita il tasto per la rimozione di elementi
	 * */
	public void setRemoveEnabled(boolean isEnabled){
		if (this.getViewType()==ViewType.WRITABLE)
		this.removeEn=isEnabled;
	}
	/**
	 * Abilita/Disabilita il tasto per l'aggiunta di elementi
	 * */
	public void setAddEnabled(boolean isEnabled){
		if (this.getViewType()==ViewType.WRITABLE)
		this.addEn=isEnabled;
	}
	/**
	 * ottiene l'indice del modulo selezionato
	 * */
	public int getSelectedIndex(){
		return this.listMod.getSelectedIndex();
	}
	/**
	 * Ottiene il modulo selezionato
	 * */
	public Module<?> getSelectedContent(){
		return listMod.getSelectedContent();
	}
	/**
	 * Aggiunge un listener che verrà avvisato all' aggiunta di un modulo
	 * */
	public void addElementAddedListener(ElementsListener listener){
		this.eladdListeners.add(listener);
	}
	/**
	 * Aggiunge un listener che verrà avvisato alla rimozione di un modulo
	 * */
	public void removeElementAddedListener(ElementsListener listener){
		this.eladdListeners.remove(listener);
	}
	@Override
	protected CPanel getReadOnlyPanel(boolean isSelected) {
		CPanel retPanel=new CPanel(new BorderLayout());
		CPanel listPanel=new CPanel();
		listPanel.setLayout(new BoxLayout(listPanel,BoxLayout.Y_AXIS));
		if (this.getHierachyNumber()>0)retPanel.add(new CLabel(this.getTag(), LabelType.H2),BorderLayout.NORTH);
		for(Module<?> mod:this.getContent()){
			listPanel.add(mod.getPanel(ViewType.ONE_LINE,false));
		}
		retPanel.add(listPanel,BorderLayout.WEST);
		return retPanel;
	}
	@Override
	protected CPanel getWritablePanel(boolean isSelected) {
		CPanel retPanel=new CPanel(new BorderLayout());
		if (this.getHierachyNumber()==1)retPanel.add(new CLabel(this.getTag(), LabelType.H2),BorderLayout.NORTH);
		CPanel listPanel=this.createList();
		this.viewerScroll=new JScrollPane(this.createViewer());
		JSplitPane split=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, listPanel,this.viewerScroll);
		retPanel.add(split);
		if (this.getHierachyNumber()>0)retPanel.setPreferredSize(new Dimension(650,300));
		return retPanel;
	}
	@Override
	public CPanel getInListPanel(boolean isSelected) {
		return CModules.formatForList(this.getTag(), CWords.getWord("LIST_ELEMENTS_NUMBER")+": "+this.listMod.getContent().size(), isSelected);
	}
	@Override
	protected void beforeFireChange(Module<?> mod) {
		if (mod instanceof ModCollection||mod instanceof ModCollectionViewer){
			this.addMode=false;
		}else if(mod.getTag().equalsIgnoreCase(CWords.getWord("CUSTOMER_TYPE"))){
			this.addMode=true;
		}else this.ignoreFire();
	}
	@Override
	protected void afterFireChange(Module<?> mod) {
		if(mod.getAncestorModule().getTag().equalsIgnoreCase(this.addModule.getTag())){
			this.fireModuleChanged(this);
		}
	}
	public Module<?>getAddModule(){
		return this.addModule;
	}
	public boolean isInAddMode(){
		return this.addMode;
	}
	@Override
	protected CPanel getOneLinePanel(boolean isSelected) {
		return this.listMod.getPanel(ViewType.ONE_LINE, isSelected);
	}
	public void setAddMode(boolean addMode){
		this.addMode=addMode;
	}
	public void addCollectionButtonListener(CollectionButtonListener listener){
		this.collectionButtonListeners.add(listener);
	}
	public void removeCollectionButtonListener(CollectionButtonListener listener){
		this.collectionButtonListeners.remove(listener);
	}
	public void fireCollectionButtonListener(int index){
		for(CollectionButtonListener lst:this.collectionButtonListeners){
			lst.onButtonPressed(this.currentViewed, index);
		}
	}
	public static final int REMOVE=0;
	public static final int ADD=1;
	private LinkedList<CollectionButtonListener> collectionButtonListeners;
	private int lastIndex=-1;
	public static final int HIDE_ADD= 400001;
	public static final int HIDE_REMOVE= 400002;
	private Module<?>currentViewed;
	private JScrollPane viewerScroll;
	private LinkedList<ElementsListener>eladdListeners;
	private ModCollection listMod;
	private Module<?>addModule;
	private boolean addEn=true;
	private boolean removeEn=true;
	private boolean addMode=false;
}
